package com.whfc.fvs.service.impl;

import com.whfc.common.enums.DelFlag;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ListData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.vs.ezviz.EzvizApi;
import com.whfc.common.vs.ezviz.entity.EzvizChannelInfo;
import com.whfc.common.vs.ezviz.entity.EzvizGbInfo;
import com.whfc.common.vs.ezviz.entity.EzvizRecordInfo;
import com.whfc.common.vs.ezviz.entity.EzvizStreamInfo;
import com.whfc.fvs.dao.FvsDeviceMapper;
import com.whfc.fvs.dao.FvsStreamMapper;
import com.whfc.fvs.dto.*;
import com.whfc.fvs.entity.FvsDevice;
import com.whfc.fvs.entity.FvsStream;
import com.whfc.fvs.enums.FvsDevicePtzOption;
import com.whfc.fvs.enums.FvsDevicePtzStatus;
import com.whfc.fvs.enums.FvsDeviceType;
import com.whfc.fvs.enums.VsPlatform;
import com.whfc.fvs.param.FvsDeviceAddParam;
import com.whfc.fvs.service.FvsPlatformService;
import com.whfc.fvs.service.factroy.FvsPlatformConstant;
import com.whfc.fvs.service.manager.FvsTokenMgr;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 萤石云GB28181服务
 *
 * @author hw
 * @version 1.0
 * @date 2021-07-13 15:09
 */
@Service(FvsPlatformConstant.EZVIZ_GB24181_SERVICE)
public class FvsEzvizVsGB28181Impl implements FvsPlatformService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 一天
     */
    private static final long ONE_DAY_MILLS = 24 * 60 * 60 * 1000;

    @Autowired
    private FvsDeviceMapper fvsDeviceMapper;

    @Autowired
    private FvsStreamMapper fvsStreamMapper;

    @Autowired
    private FvsTokenMgr fvsTokenMgr;

    @Override
    public void addDevice(FvsDeviceDTO fvsDeviceDTO, FvsDeviceAddParam deviceAddParam) {
        String gbId = deviceAddParam.getGbId();
        if (StringUtils.isEmpty(gbId)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "国标ID不能为空.");
        }
        String deviceSerial = deviceAddParam.getUsername();
        if (StringUtils.isEmpty(deviceSerial)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "项目id不能为空.");
        }
        String password = deviceAddParam.getPassword();
        if (StringUtils.isEmpty(password)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "License不能为空.");
        }
        Integer deviceType = deviceAddParam.getDeviceType();
        if (deviceType == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "设备类型不能为空.");
        }
        String accessToken = fvsTokenMgr.getEzvizAccessToken(deviceAddParam.getDeptId());
        List<EzvizGbInfo> ezvizGbInfos = EzvizApi.getGbLicenseList(accessToken, deviceSerial);
        if (ezvizGbInfos.isEmpty()) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "绑定信息不存在");
        }
        try {
            EzvizApi.getStreamUrl(accessToken, deviceSerial + ":" + gbId, 1);
        } catch (Exception e) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "填写数据错误");
        }

        FvsDevice fvsDevice = new FvsDevice();
        fvsDevice.setId(fvsDeviceDTO.getId());
        fvsDevice.setName(deviceAddParam.getName());
        fvsDevice.setGbId(gbId);
        fvsDevice.setDeptId(deviceAddParam.getDeptId());
        fvsDevice.setPtz(FvsDevicePtzStatus.NOT_SUPPORT_PTZ.getValue());
        fvsDevice.setUsername(deviceSerial);
        fvsDevice.setPassword(password);
        fvsDevice.setDeviceType(deviceType);
        fvsDevice.setStreamStatus(1);
        fvsDeviceMapper.updateByPrimaryKeySelective(fvsDevice);
        if (FvsDeviceType.DVR.getValue().equals(fvsDevice.getDeviceType())) {
            //获取萤石云登录token
            List<EzvizChannelInfo> list = EzvizApi.getChannelList(accessToken, deviceSerial + ":" + gbId);
            List<EzvizChannelInfo> validList = list.stream().filter(EzvizChannelInfo::getRelatedIpc).collect(Collectors.toList());
            validList.forEach(ezvizChannelInfo -> {
                String zdeviceSerial = ezvizChannelInfo.getDeviceSerial();
                String zgbId = zdeviceSerial.substring(zdeviceSerial.indexOf(":") + 1);
                FvsDevice device = new FvsDevice();
                BeanUtils.copyProperties(fvsDevice, device);
                device.setId(null);
                device.setDeptId(fvsDevice.getDeptId());
                device.setPid(fvsDevice.getId());
                device.setGroupId(deviceAddParam.getGroupId());
                device.setDeviceType(FvsDeviceType.IPC.getValue());
                device.setChannelNo(ezvizChannelInfo.getChannelNo());
                device.setPlatform(VsPlatform.EZVIZ_GB28181.getValue().toString());
                device.setDeviceStatus(ezvizChannelInfo.getStatus() == 1 ? 1 : 0);
                device.setName(ezvizChannelInfo.getIpcSerial());
                device.setGbId(zgbId);
                device.setPtz(FvsDevicePtzStatus.SUPPORT_PTZ.getValue());
                fvsDeviceMapper.insertSelective(device);
            });
        }

    }

    @Override
    public void deleteDevice(FvsDeviceDTO fvsDeviceDTO) {
        if (FvsDeviceType.DVR.getValue().equals(fvsDeviceDTO.getDeviceType())) {
            //逻辑删除硬盘录像机下面的所有摄像头
            fvsDeviceMapper.logicDeleteByPid(fvsDeviceDTO.getId());
        }
    }

    @Override
    public String getSnapshotUrl(FvsDeviceDTO fvsDeviceDTO) {
        return null;
    }

    @Override
    public FvsStreamDTO getStreamUrl(FvsDeviceDTO fvsDeviceDTO) {
        String accessToken = fvsTokenMgr.getEzvizAccessToken(fvsDeviceDTO.getDeptId());
        String deviceSerial = fvsDeviceDTO.getUsername() + ":" + fvsDeviceDTO.getGbId();
        Integer channelNo = fvsDeviceDTO.getChannelNo();
        FvsStream fvsStream = fvsStreamMapper.selectStreamByDeviceId(fvsDeviceDTO.getId());
        boolean isNeedRefresh = false;
        //没有视频播放地址
        if (fvsStream == null) {
            isNeedRefresh = true;
            fvsStream = new FvsStream();
        }
        //视频播放地址过期
        else {
            long timeDiff = fvsStream.getExpireTime().getTime() - System.currentTimeMillis();
            if (timeDiff < ONE_DAY_MILLS) {
                isNeedRefresh = true;
            }
        }
        if (isNeedRefresh) {
            EzvizStreamInfo streamUrl = EzvizApi.getStreamUrl(accessToken, deviceSerial, channelNo);
            fvsStream.setDeviceId(fvsDeviceDTO.getId());
            fvsStream.setEzopen(streamUrl.getEzopen());
            fvsStream.setEzopenHd(streamUrl.getEzopenHd());
            fvsStream.setHls(streamUrl.getHls());
            fvsStream.setHlsHd(streamUrl.getHlsHd());
            fvsStream.setRtmp(streamUrl.getRtmp());
            fvsStream.setRtmpHd(streamUrl.getRtmpHd());
            fvsStream.setExpireTime(streamUrl.getExpireTime());
            fvsStream.setDelFlag(DelFlag.UNDELETE.getValue());
            fvsStreamMapper.insertOrUpdate(fvsStream);
        }
        FvsStreamDTO streamDTO = new FvsStreamDTO();
        BeanUtils.copyProperties(fvsStream, streamDTO);
        return streamDTO;
    }

    @Override
    public ListData<FvsRecordDTO> getRecordList(FvsDeviceDTO fvsDeviceDTO, Date startTime, Date endTime) {
        //获取登录token和设备序列号
        String accessToken = fvsTokenMgr.getEzvizAccessToken(fvsDeviceDTO.getDeptId());
        String deviceSerial = fvsDeviceDTO.getUsername() + ":" + fvsDeviceDTO.getGbId();

        ListData<FvsRecordDTO> listData = new ListData<>();
        List<FvsRecordDTO> list = new ArrayList<>();
        List<EzvizRecordInfo> recordList = EzvizApi.getRecordList(accessToken, deviceSerial, fvsDeviceDTO.getChannelNo(), startTime, endTime);
        if (recordList == null || recordList.isEmpty()) {
            listData.setList(list);
            return listData;
        }
        for (EzvizRecordInfo record : recordList) {
            FvsRecordDTO appFvsRecordDTO = new FvsRecordDTO();
            Date start = new Date(record.getStartTime());
            Date end = new Date(record.getEndTime());
            appFvsRecordDTO.setStartTime(start);
            appFvsRecordDTO.setEndTime(end);
            String recordUrl = record.getRecordURL();
            appFvsRecordDTO.setRecordUrl(recordUrl);
            list.add(appFvsRecordDTO);
        }
        listData.setList(list);
        return listData;
    }

    @Override
    public void ptz(FvsDeviceDTO fvsDeviceDTO, FvsDevicePtzOption devicePtzOption) {

    }

    @Override
    public FvsTokenDTO getToken(Integer deptId) {
        FvsTokenDTO fvsTokenDTO = new FvsTokenDTO();
        fvsTokenDTO.setToken(fvsTokenMgr.getEzvizAccessToken(deptId));
        FvsSettingDTO fvsSettingDTO = fvsTokenMgr.getFvsSetting(deptId, VsPlatform.HIK_EZVIZ);
        String appKey = fvsSettingDTO != null ? fvsSettingDTO.getAppKey() : "";
        fvsTokenDTO.setAppKey(appKey);
        return fvsTokenDTO;
    }


}
